import 'dart:async';

import 'package:ty_smart_watch/bean/alarm_bean.dart';
import 'package:ty_smart_watch/bean/base_data_bean.dart';
import 'package:ty_smart_watch/bean/gps_bean.dart';
import 'package:ty_smart_watch/bean/sport_data_bean.dart';
import 'package:ty_smart_watch/bean/sport_recorder_bean.dart';
import 'package:ty_smart_watch/utils/util.dart';

import '../bean/receive_data_bean.dart';
import '../common/function_id.dart';
import '../utils/Log.dart';

typedef MyCallback = void Function(int id);

/// 手表到App 数据解析类
class DataAnalysis {
  //region 单例模式
  static DataAnalysis? _instance;

  factory DataAnalysis() => _getInstance()!;

  static DataAnalysis? get instance => _getInstance();

  static DataAnalysis? _getInstance() {
    _instance ??= DataAnalysis._internal();
    return _instance;
  }

  DataAnalysis._internal() {
    _init();
  }

  _init() {}

  //endregion

  static const _PACKAGE_DATA_TIME_OUT = Duration(milliseconds: 500);
  static final Map<int, List<int>> _functionMap = {};
  var mFunctionHandler = MyHandler(listener: (int id) {
    _functionMap.remove(id);
  });

  //region 解析数据

  ReceiveDataBean analysisReceiveData(List<int> mData) {
    int currFrame = Util.instance!.toInt(mData, CURRENT_FRAME_INDEX, CURRENT_FRAME_SIZE);
    int totalFrame = Util.instance!.toInt(mData, TOTAL_FRAME_INDEX, TOTAL_FRAME_SIZE);
    int functionFlag = Util.instance!.toInt(mData, FUNCTION_FLAG_INDEX, FUNCTION_FLAG_SIZE);
    int checkSum = Util.instance!.toUShort(mData, CHECK_SUM_INDEX, CHECK_SUM_SIZE);
    int packageLength = Util.instance!.toInt(mData, PACKAGE_LENGTH_INDEX, PACKAGE_LENGTH_SIZE);
    int functionId = Util.instance!.toInt(mData, FUNCTION_ID_INDEX, FUNCTION_ID_SIZE);
    int dataLength = Util.instance!.toInt(mData, DATA_LENGTH_INDEX, DATA_LENGTH_SIZE);

    List<int> data = copyFrom(mData, DATA_INDEX, dataLength);

    ReceiveDataBean dataBean = ReceiveDataBean(currFrame, totalFrame, functionFlag,
        checkSum.toInt(), packageLength.toInt(), functionId.toInt(), dataLength.toInt());

    Log.d("收到数据: $dataBean");

    switch (dataBean.functionId) {
      //region 基础信息类
      //芯片信息
      case CHIP_INFO:
        dataBean.setLongData("transMode", Util.instance!.toLong(data, 0, 1)); //传输方式
        dataBean.setLongData("chipFactory", Util.instance!.toLong(data, 1, 2)); //芯片厂商
        String chipType = Util.instance!.byteArrayToString(data.sublist(3, dataLength.toInt() - 3));
        dataBean.setStringData("chipType", chipType); //芯片型号
        break;
      //设备版本号
      case DEVICE_VERSION:
        dataBean.setLongData("h1", Util.instance!.toLong(data, 0, 1));
        dataBean.setLongData("h2", Util.instance!.toLong(data, 1, 1));
        dataBean.setLongData("s1", Util.instance!.toLong(data, 2, 1));
        dataBean.setLongData("s2", Util.instance!.toLong(data, 3, 1));
        dataBean.setLongData("s3", Util.instance!.toLong(data, 4, 1));
        String model = Util.instance!.byteArrayToString(data.sublist(5, dataLength.toInt()));
        dataBean.setStringData("model", model);
        break;
      //endregion

      //region 绑定信息类
      //绑定请求
      case BIND:
        dataBean.setLongData("bind", Util.instance!.toLong(data, 0, 1));
        break;
      //解绑请求
      case UN_BIND:
        dataBean.setLongData("unbind", Util.instance!.toLong(data, 0, 1));
        break;
      //配对请求
      case PAIR:
        break;
      //功能列表
      case FUNCTION_LIST:
        dataBean.setLongData("0", Util.instance!.toLong(data, 0, 1));
        dataBean.setLongData("1", Util.instance!.toLong(data, 1, 1));
        dataBean.setLongData("2", Util.instance!.toLong(data, 2, 1));
        dataBean.setLongData("3", Util.instance!.toLong(data, 3, 1));
        dataBean.setLongData("4", Util.instance!.toLong(data, 4, 1));
        dataBean.setLongData("5", Util.instance!.toLong(data, 5, 1));
      //endregion

      //region 设置消息类
      case STEP_TARGET:
        dataBean.setLongData("stepTarget", Util.instance!.toLong(data, 0, 4));
        dataBean.setLongData(SUCCESS, Util.instance!.toLong(data, 3, 1));
        break;
      //亮屏时间
      case BRIGHTEN_SCREEN_TIME:
        var temp = Util.instance!.toLong(data, 0, 1);
        Log.d("temp:  $temp ");
        dataBean.setLongData("brightScreenTime", Util.instance!.toLong(data, 0, 1));
        dataBean.setLongData(SUCCESS, Util.instance!.toLong(data, 1, 1));
        break;
      //久坐提醒
      case LONG_SIT:
        dataBean.setLongData("switch", Util.instance!.toLong(data, 0, 1));
        dataBean.setLongData("startHour", Util.instance!.toLong(data, 1, 1));
        dataBean.setLongData("startMinute", Util.instance!.toLong(data, 2, 1));
        dataBean.setLongData("endHour", Util.instance!.toLong(data, 3, 1));
        dataBean.setLongData("endMinute", Util.instance!.toLong(data, 4, 1));
        dataBean.setLongData("duration", Util.instance!.toLong(data, 5, 1));
        dataBean.setLongData(SUCCESS, Util.instance!.toLong(data, 6, 1));
        break;

      //勿扰设置
      case DO_NOT_DISTURB:
        dataBean.setLongData("switch", Util.instance!.toLong(data, 0, 1));
        dataBean.setLongData("startHour", Util.instance!.toLong(data, 1, 1));
        dataBean.setLongData("startMinute", Util.instance!.toLong(data, 2, 1));
        dataBean.setLongData("endHour", Util.instance!.toLong(data, 3, 1));
        dataBean.setLongData("endMinute", Util.instance!.toLong(data, 4, 1));
        dataBean.setLongData(SUCCESS, Util.instance!.toLong(data, 5, 1));
        break;

      //震动设置
      case SHAKE:
        dataBean.setLongData("level", Util.instance!.toLong(data, 0, 1));
        dataBean.setLongData("times", Util.instance!.toLong(data, 1, 1));
        dataBean.setLongData(SUCCESS, Util.instance!.toLong(data, 2, 1));
        break;
      //抬手亮屏设置
      case HAND_BRIGHTEN_SCREEN:
        dataBean.setLongData("switch", Util.instance!.toLong(data, 0, 1));
        dataBean.setLongData("startHour", Util.instance!.toLong(data, 1, 1));
        dataBean.setLongData("startMinute", Util.instance!.toLong(data, 2, 1));
        dataBean.setLongData("endHour", Util.instance!.toLong(data, 3, 1));
        dataBean.setLongData("endMinute", Util.instance!.toLong(data, 4, 1));
        dataBean.setLongData(SUCCESS, Util.instance!.toLong(data, 5, 1));
        break;

      //12/24小时
      case HOUR_TYPE:
        dataBean.setLongData("type", Util.instance!.toLong(data, 0, 1));
        dataBean.setLongData(SUCCESS, Util.instance!.toLong(data, 1, 1));
        break;

      //语言设置
      case LANGUAGE:
        dataBean.setLongData("language", Util.instance!.toLong(data, 0, 1));
        dataBean.setLongData(SUCCESS, Util.instance!.toLong(data, 1, 1));
        break;

      //闹钟设置
      case ALARM:
        if (dataLength.toInt() <= 2) {
          //无闹钟
          return dataBean;
        }
        List<AlarmBean> alarmList = [];
        int type = Util.instance!.toInt(data, 0, 1);
        for (int i = 0;
            i < (dataLength.toInt() - 1 /*增加/删除/修改*/ - 1 /*结尾0x00*/) ~/ 5 /*5位一个*/;
            i++) {
          int id = Util.instance!.toInt(data, 1 + i * 5, 1);
          int switchValue = Util.instance!.toInt(data, 2 + i * 5, 1);
          int repeat = Util.instance!.toInt(data, 3 + i * 5, 1) & 1;
          List<int> dayOfWeek = [];
          for (int position = 0; position < 7; position++) {
            int bit = (Util.instance!.toInt(data, 3 + i * 5, 1) >> (position + 1)) & 1;
            print("闹钟重复日数据解析  >>   position: ${position + 1}   ===   bit: $bit");
            dayOfWeek.add(bit);
          }
          int hour = Util.instance!.toInt(data, 4 + i * 5, 1);
          int minute = Util.instance!.toInt(data, 5 + i * 5, 1);

          AlarmBean alarm = AlarmBean(id, type, switchValue, repeat, dayOfWeek, hour, minute);
          alarmList.add(alarm);
        }

        dataBean.setAlarmData("alarm", alarmList);
        dataBean.setLongData(SUCCESS, Util.instance!.toLong(data, 6, 1));
        break;

      //消息通知开关
      case NOTIFICATION_SWITCH:
        // 总开关（0：关闭，1：打开）
        int isSwitch = Util.instance!.byteArrayToLong(data, 0, 1);
        dataBean.setLongData("notification", isSwitch);
        List<int> appNotifyList = [];

        for (int i = 1; i <= 4; i++) {
          List<int> tempList = [];
          for (int position = 0; position < 8; position++) {
            int bit = (Util.instance!.byteArrayToInt(data, i, 1) >> position) & 1;
            tempList.add(bit);
          }
          appNotifyList.addAll(tempList);
        }
        dataBean.setIntListData("app_notification", appNotifyList);
        break;

      //定时心率
      case TIME_HEART:
        dataBean.setLongData("switch", Util.instance!.toLong(data, 0, 1));
        dataBean.setLongData("startHour", Util.instance!.toLong(data, 1, 1));
        dataBean.setLongData("startMinute", Util.instance!.toLong(data, 2, 1));
        dataBean.setLongData("endHour", Util.instance!.toLong(data, 3, 1));
        dataBean.setLongData("endMinute", Util.instance!.toLong(data, 4, 1));
        dataBean.setLongData("duration", Util.instance!.toLong(data, 5, 1));
        dataBean.setLongData(SUCCESS, Util.instance!.toLong(data, 6, 1));
        break;

      //喝水提醒
      case DRINK_REMIND:
        dataBean.setLongData("switch", Util.instance!.toLong(data, 0, 1));
        dataBean.setLongData("startHour", Util.instance!.toLong(data, 1, 1));
        dataBean.setLongData("startMinute", Util.instance!.toLong(data, 2, 1));
        dataBean.setLongData("endHour", Util.instance!.toLong(data, 3, 1));
        dataBean.setLongData("endMinute", Util.instance!.toLong(data, 4, 1));
        dataBean.setLongData("duration", Util.instance!.toLong(data, 5, 1));
        dataBean.setLongData(SUCCESS, Util.instance!.toLong(data, 6, 1));
        break;

      //吃药提醒
      case MEDICINE_REMIND:
        dataBean.setLongData("switch", Util.instance!.toLong(data, 0, 1));
        dataBean.setLongData("hour", Util.instance!.toLong(data, 1, 1));
        dataBean.setLongData("minute", Util.instance!.toLong(data, 2, 1));
        break;
      //生理期提醒
      case PERIOD:
        dataBean.setLongData("switch", Util.instance!.toLong(data, 0, 1));
        dataBean.setLongData("year", Util.instance!.toLong(data, 1, 1));
        dataBean.setLongData("month", Util.instance!.toLong(data, 2, 1));
        dataBean.setLongData("day", Util.instance!.toLong(data, 3, 1));
        dataBean.setLongData("duration", Util.instance!.toLong(data, 4, 1));
        dataBean.setLongData(SUCCESS, Util.instance!.toLong(data, 5, 1));
        break;

      //定时体温
      case TIMING_BODY_TEMPERATURE:
        dataBean.setLongData("switch", Util.instance!.toLong(data, 0, 1));
        dataBean.setLongData("startHour", Util.instance!.toLong(data, 1, 1));
        dataBean.setLongData("startMinute", Util.instance!.toLong(data, 2, 1));
        dataBean.setLongData("endHour", Util.instance!.toLong(data, 3, 1));
        dataBean.setLongData("endMinute", Util.instance!.toLong(data, 4, 1));
        dataBean.setLongData("duration", Util.instance!.toLong(data, 5, 1));
        dataBean.setLongData(SUCCESS, Util.instance!.toLong(data, 6, 1));
        break;

      //防丢
      case ANTI_LOST:
        dataBean.setLongData("switch", Util.instance!.toLong(data, 0, 1));
        break;

      //公英制
      case INCH_TYPE:
        dataBean.setLongData("inch", Util.instance!.toLong(data, 0, 1));
        break;

      //天气温度单位
      case TEMPERATURE_TYPE:
        dataBean.setLongData("temperatureType", Util.instance!.toLong(data, 0, 1));
        break;

      //SOS
      case SOS:
        if (dataLength.toInt() <= 2) {
          //无SOS联系人
          return dataBean;
        }
        dataBean.setLongData("type", Util.instance!.toLong(data, 0, 1));
        dataBean.setLongData("id", Util.instance!.toLong(data, 1, 1));
        var number = Util.instance!.byteArrayToString(data.sublist(2, 22)).trim();
        var name =
            Util.instance!.byteArrayToString(data.sublist(22, dataLength.toInt() - 1)).trim();
        dataBean.setStringData("number", number);
        dataBean.setStringData("name", name);
        dataBean.setLongData("success", Util.instance!.toLong(data, dataLength.toInt() - 1, 1));
        break;

      //表盘设置

      //手表控制电话
      case PHONE_CONTROL:
        dataBean.setLongData("switch", Util.instance!.toLong(data, 0, 1));
        break;

      //找手机
      case FIND_PHONE:
        dataBean.setLongData("type", Util.instance!.toLong(data, 0, 1));
        break;

      //找手表

      //拍照控制
      case CAMERA_CONTROL:
        dataBean.setLongData("switch", Util.instance!.toLong(data, 0, 1));
        break;
      //用户信息设置
      case USER_INFO:
        dataBean.setLongData("system", Util.instance!.toLong(data, 0, 1));
        dataBean.setLongData("sex", Util.instance!.toLong(data, 1, 1));
        dataBean.setLongData("age", Util.instance!.toLong(data, 2, 1));
        dataBean.setLongData("height", Util.instance!.toLong(data, 3, 2));
        dataBean.setLongData("weight", Util.instance!.toLong(data, 5, 2));
        break;
      //自定义表盘

      //endregion

      //region 数据消息类
      //实时数据
      case REAL_TIME_DATA:
        //步数数据
        dataBean.setLongData("stepData", Util.instance!.toLong(data, 0, 4));
        //卡路里（卡）
        dataBean.setLongData("calorie", Util.instance!.toLong(data, 4, 4));
        //距离（米）
        dataBean.setLongData("distance", Util.instance!.toLong(data, 8, 4));
        //心率
        dataBean.setLongData("heart", Util.instance!.toLong(data, 12, 1));
        //电量（百分比）
        dataBean.setLongData("battery", Util.instance!.toLong(data, 13, 1));
        break;

      //运动
      case SPORT_RECORDER:
        if (dataLength.toInt() == 0) return dataBean;

        int block = data.length ~/ 26;
        List<SportBean> dataList = [];
        for (int i = 0; i < block; i++) {
          int type = Util.instance!.toInt(data, i * 26 + 0, 1);
          int startTimeStamp = (Util.instance!.toLong(data, i * 26 + 1, 4) *
                  1000 /* - CommonViewModel().getTimeZoneRawOffset()*/)
              .toInt();
          int duration = Util.instance!.toLong(data, i * 26 + 5, 4);
          int step = (Util.instance!.toLong(data, i * 26 + 9, 4) == 0xFFFFFFFF)
              ? -1
              : Util.instance!.toLong(data, i * 26 + 9, 4);
          int calorie = Util.instance!.toLong(data, i * 26 + 13, 4);
          int distance = (Util.instance!.toLong(data, i * 26 + 17, 4) == 0xFFFFFFFF)
              ? -1
              : Util.instance!.toLong(data, i * 26 + 17, 4);
          int heart = Util.instance!.toInt(data, i * 26 + 21, 1);
          String pace = (Util.instance!.toLong(data, i * 26 + 22, 2) == 0xFFFF)
              ? "不支持"
              : "${data[i * 26 + 22].toInt()}分${data[i * 26 + 23].toInt()}秒/公里";
          int cadence = (Util.instance!.toLong(data, i * 26 + 24, 2) == 0xFFFF)
              ? -1
              : Util.instance!.toLong(data, i * 26 + 24, 2);

          SportBean bean = SportBean(
              type, startTimeStamp, duration, step, calorie, distance, heart, pace, cadence);
          dataList.add(bean);
        }
        dataBean.setSportDataList(dataList);
        break;

      //心率 次/分
      case HEART:
        if (dataLength.toInt() == 0) return dataBean;
        int block = (data.length) ~/ 5;
        List<BaseDataBean> dataList = [];
        for (int i = 0; i < block; i++) {
          BaseDataBean bean = BaseDataBean(HEART, Util.instance!.toLong(data, i * 5 + 0, 4),
              Util.instance!.toLong(data, i * 5 + 4, 1).toInt());
          dataList.add(bean);
        }
        dataBean.setBaseDataListData("heart", dataList);
        break;

      //血糖 mmol/l
      case BLOOD_GLUCOSE:
        if (dataLength.toInt() == 0) return dataBean;
        int block = data.length ~/ 6;
        List<BaseDataBean> dataList = [];
        for (int i = 0; i < block; i++) {
          BaseDataBean bean = BaseDataBean(BLOOD_GLUCOSE, Util.instance!.toLong(data, i * 6 + 0, 4),
              Util.instance!.toLong(data, i * 6 + 4, 2));
          dataList.add(bean);
        }
        dataBean.setBaseDataListData("bloodGlucose", dataList);
        break;
      //血压
      case BLOOD_PRESSURE:
        if (dataLength.toInt() == 0) return dataBean;
        int block = data.length ~/ 6;
        List<BaseDataBean> bloodPressureList = [];
        for (int i = 0; i < block; i++) {
          int shouSuo = Util.instance!.toInt(data, i * 6 + 4, 1);
          int shuZhang = Util.instance!.toInt(data, i * 6 + 5, 1);
          BaseDataBean bean =
              BaseDataBean(BLOOD_PRESSURE, Util.instance!.toLong(data, i * 6 + 0, 4), 0);
          bean.arg1 = shouSuo.toString();
          bean.arg2 = shuZhang.toString();
          bloodPressureList.add(bean);
        }
        dataBean.setBaseDataListData("bloodPressure", bloodPressureList);
        break;
      //血氧
      case BLOOD_OXYGEN:
        if (dataLength.toInt() == 0) return dataBean;
        int block = data.length ~/ 5;
        List<BaseDataBean> dataList = [];
        for (int i = 0; i < block; i++) {
          BaseDataBean bean = BaseDataBean(BLOOD_OXYGEN, Util.instance!.toLong(data, i * 5 + 0, 4),
              Util.instance!.toInt(data, i * 5 + 4, 1));
          dataList.add(bean);
        }
        dataBean.setBaseDataListData("bloodOxygen", dataList);
        break;
      //睡眠
      case SLEEP:
        if (dataLength.toInt() == 0) return dataBean;

        //浅睡眠时间
        int lightSleep = Util.instance!.toLong(data, 0, 2);
        //深睡眠时间
        int deepSleep = Util.instance!.toLong(data, 2, 2);
        //快速眼动时间
        int eyeMovements = Util.instance!.toLong(data, 4, 2);
        //睡眠详细数据
        List<BaseDataBean> dataList = [];

        int block = (data.length - 6) ~/ 5;
        for (int i = 0; i < block; i++) {
          BaseDataBean bean = BaseDataBean(SLEEP, Util.instance!.toLong(data, i * 5 + 6, 4),
              Util.instance!.toInt(data, i * 5 + 10, 1));
          dataList.add(bean);
        }
        dataBean.setBaseDataListData("sleep", dataList);
        dataBean.setIntListData("sleepTime", [lightSleep, deepSleep, eyeMovements]);
        break;

      case HRV:
        if (dataLength.toInt() == 0) return dataBean;

        int block = data.length ~/ 6;
        List<BaseDataBean> dataList = [];
        for (int i = 0; i < block; i++) {
          BaseDataBean bean = BaseDataBean(HRV, Util.instance!.toLong(data, i * 6 + 0, 4),
              Util.instance!.toLong(data, i * 6 + 4, 2));
          dataList.add(bean);
        }
        dataBean.setBaseDataListData("hrv", dataList);
        break;

      //GPS
      case GPS:
//                dataBean.setLongData(Cons.Common.TIME_STAMP,  Util.instance!.toLong(data,0, 4))
//                //卫星数量
//                dataBean.setLongData("satelliteNumber",  Util.instance!.toLong(data,4, 1))
//                //经度 longitude
//                //(第5byte最高位作判断东经或西经，0:西经，1:东经)
//                //数据会保留6位小数，上报数据会扩大。
//                //例如:125.369874W,上报的数据会变成125369874
//                dataBean.setLongData("longitude",  Util.instance!.toLong(data,5, 4))
//                //纬度 latitude
//                // (第9byte最高位作判断东经或西经，0:南纬，1:北纬)
//                //数据会保留6位小数，上报数据会扩大。
//                //例如:75.369874S,上报的数据会变成75369874"
//                dataBean.setLongData("latitude",  Util.instance!.toLong(data,9, 5))
        if (dataLength.toInt() == 0) return dataBean;

        int block = data.length ~/ 14;
        List<GpsBean> dataList = [];
        for (int i = 0; i < block; i++) {
          GpsBean bean = GpsBean(
              Util.instance!.toLong(data, i * 14 + 0, 4),
              Util.instance!.toInt(data, i * 14 + 4, 1),
              Util.instance!.toLong(data, i * 14 + 5, 4),
              Util.instance!.toLong(data, i * 14 + 9, 5));
          dataList.add(bean);
        }
        dataBean.setGpsListData("gps", dataList);
        break;

      //车辆状态
      case CAR_STATE:
        //时间戳
        dataBean.setLongData(TIME_STAMP, Util.instance!.toLong(data, 0, 4));
        //车辆状态
        var carState = data[4];
        //门状态
        dataBean.setLongData("doorState", Util.instance!.getIndexToLong(carState, 0));
        //车窗状态
        dataBean.setLongData("windowState", Util.instance!.getIndexToLong(carState, 1));
        //发动机状态
        dataBean.setLongData("engineState", Util.instance!.getIndexToLong(carState, 2));
        //空调状态
        dataBean.setLongData("airState", Util.instance!.getIndexToLong(carState, 3));
        //后备箱状态
        dataBean.setLongData("backBoxState", Util.instance!.getIndexToLong(carState, 4));
        //燃油剩余量（0~99）百分比
        dataBean.setLongData("oilSurplus", Util.instance!.toLong(data, 5, 1));
        //高压电量剩余（0~99）百分比
        dataBean.setLongData("highVoltageResidual", Util.instance!.toLong(data, 6, 1));
        //低压电池电压
        dataBean.setLongData("LowVoltage", Util.instance!.toLong(data, 7, 1));
        //车速（km/h)
        dataBean.setLongData("speed", Util.instance!.toLong(data, 8, 1));
        //胎压（单位：0.1Bar)
        dataBean.setLongData("tirePressure", Util.instance!.toLong(data, 9, 4));
        //水温（℃）
        dataBean.setLongData("waterTemperature", Util.instance!.toLong(data, 13, 1));
        //"油耗（百公里/升） 转换成整数，油耗 * 10"
        dataBean.setLongData("oilWear", Util.instance!.toLong(data, 14, 1));
        //总公里数（km)
        dataBean.setLongData("totalMileage", Util.instance!.toLong(data, 15, 4));
        //保养里程(km)
        dataBean.setLongData("maintainMileage", Util.instance!.toLong(data, 19, 4));
        //故障码（保留）
        // dataBean.dataMap["errorCode", Util.instance!.toLong(data,23,n )
        break;
      //车辆控制 无此项，该项仅由APP发送
      case CAR_CONTROL:
        break;

      //心电 TODO
      case ECG:
        dataBean.setLongData(TIME_STAMP, Util.instance!.toLong(data, 0, 4));
        // 4~n 每四个字节为一组数据解析心电值
        int startIndex = 4;
        int dataSize = (dataLength - 4) ~/ 4;
        for (int i = 0; i < dataSize; i++) {
          int heart = Util.instance!.toLong(data, startIndex + (i * 4), 4);
          dataBean.setLongData("$i", heart);
        }
        break;

      //RRI
      case RRI:
        dataBean.setLongData(TIME_STAMP, Util.instance!.toLong(data, 0, 4));
        dataBean.setLongData("rri", Util.instance!.toLong(data, 4, 4));
        break;

      //大气压值
      case BAROMETRIC_PRESSURE:
        dataBean.setLongData(TIME_STAMP, Util.instance!.toLong(data, 0, 4));
        dataBean.setLongData("barometricPressure", Util.instance!.toLong(data, 4, 4));
        break;

      //体温
      case BODY_TEMPERATURE:
//                dataBean.setLongData(Cons.Common.TIME_STAMP,  Util.instance!.toLong(data,0, 4))
//                //"体温值（摄氏度） 转化成整数，体温值 * 10"
//                dataBean.setLongData("bodyTemperature",  Util.instance!.toLong(data,4, 2))
//                //"环境温度值（摄氏度） 转化成整数，体温值 * 10 bit15:1,代表负数；0，代表正数"
//                val environmentTemperature = (data[6].toLong() shl 8) or (data[7].toLong() and 0xFF)
//                dataBean.setLongData("environmentTemperature", environmentTemperature)

        int block = data.length ~/ 8;

        List<BaseDataBean> temperatureList = [];
        for (int i = 0; i < block; i++) {
          int body = Util.instance!.toInt(data, i * 8 + 4, 2);
          int environment = ((data[i * 8 + 6].toInt() << 8) | (data[i * 8 + 7].toInt() & 0xFF));
          BaseDataBean bean =
              BaseDataBean(BODY_TEMPERATURE, Util.instance!.toLong(data, i * 8 + 0, 4), 0);
          bean.arg1 = body.toString();
          bean.arg2 = environment.toString();
          temperatureList.add(bean);
        }
        dataBean.setBaseDataListData("temperature", temperatureList);
        break;

      //车辆坐标范围
      case CAR_COORDINATE_RANGE:
        break;

      //跳绳数据
      case JUMP_ROPE:
        break;

      //Gsensor
      case G_SENSOR:
        //时间戳
        dataBean.setLongData(TIME_STAMP, Util.instance!.toLong(data, 0, 4));
        //步数
        int step = Util.instance!.toLong(data, 4, 4);
        dataBean.setLongData("stepData", step);
        //卡路里（卡）
        int cal = Util.instance!.toLong(data, 8, 4);
        dataBean.setLongData("calorie", cal);
        //距离（米）
        int distance = Util.instance!.toLong(data, 12, 4);
        dataBean.setLongData("distance", distance);
        break;

      //region 推送消息类型
      //音乐控制
      case MUSIC_CONTROL:
        Log.d("音乐控制，调整大小声");
        dataBean.setLongData("volume", Util.instance!.toLong(data, 0, 1));
        break;
      //时间更新请求
      case TIME_UPDATE:
        if (dataLength.toInt() == 0) {
          //数据长度为0，请求时间更新
          Log.d("数据长度为0，请求时间更新 ");
        }
        break;
      //endregion

      default:
        Log.d("未找到解析数据ID: $functionId");
        break;
    }
    return dataBean;
  }

//endregion

//region 组装数据
  List<int>? packageData(List<int> rawData) {
    final int currFrame = Util.instance!.toInt(rawData, CURRENT_FRAME_INDEX, CURRENT_FRAME_SIZE);
    final int totalFrame = Util.instance!.toInt(rawData, TOTAL_FRAME_INDEX, TOTAL_FRAME_SIZE);

    // 总帧数为1，说明是完整数据，直接发回去
    if (totalFrame == 1) return rawData;

    var functionId = Util.instance!.toUShort(rawData, FUNCTION_ID_INDEX, FUNCTION_ID_SIZE);
    var dataLength = Util.instance!.toUShort(rawData, DATA_LENGTH_INDEX, DATA_LENGTH_SIZE);
    List<int> data = copyFrom(rawData, DATA_INDEX, dataLength);

    // 总帧数大于1，需要拼装
    if (currFrame == 1) {
      // 第一帧 将数据直接存入
      Log.d("第一帧 $rawData");
      _functionMap[functionId] = rawData;
      mFunctionHandler.sendEmptyMessageDelayed(functionId.toInt(), _PACKAGE_DATA_TIME_OUT);
      return null;
    } else if (currFrame < totalFrame) {
      //中间帧 进行数据拼装
      //拿到之前本地的数据
      List<int>? tempData = _functionMap[functionId];
      if (tempData == null) {
        //本地数据获取失败
        Log.d("中间帧 缺少前一帧");
        mFunctionHandler.sendEmptyMessage(functionId.toInt());
      } else {
        //判断是否丢帧
        //本地存储的帧索引
        var tempFrame = tempData[CURRENT_FRAME_INDEX];
        if (currFrame - tempFrame != 1) {
          Log.d("出现丢包  >> currFrame:$currFrame ::  tempFrame:$tempFrame");
          mFunctionHandler.sendEmptyMessage(functionId.toInt());
          return null;
        }
        //更新帧索引
        tempData[CURRENT_FRAME_INDEX] = currFrame;

        //计算新的数据包的数据长度(dataLength)
        var tempPackageLength =
            Util.instance!.toUShort(tempData, DATA_LENGTH_INDEX, DATA_LENGTH_SIZE);
        var newPackageLength = tempPackageLength + dataLength;
        var packageLength = Util.instance!.short2Bytes(newPackageLength);
        tempData[DATA_LENGTH_INDEX] = packageLength[0];
        tempData[DATA_LENGTH_INDEX + 1] = packageLength[1];

        //拼接数据
        List<int> newResult = tempData;
        newResult.addAll(data);

        //存入本地
        _functionMap[functionId] = newResult;
        Log.d("中间帧: $newResult");
      }
      //发送超时信息
      mFunctionHandler.removeMessages(functionId);
      mFunctionHandler.sendEmptyMessageDelayed(functionId.toInt(), _PACKAGE_DATA_TIME_OUT);
      return null;
    } else {
      //当前帧==总帧数 最后一帧
      //拿到之前本地的数据
      List<int>? tempData = _functionMap[functionId];
      if (tempData == null) {
        //本地数据获取失败
        Log.d("最后一帧 缺少前一帧");
        mFunctionHandler.sendEmptyMessage(functionId);
        return null;
      } else {
        mFunctionHandler.removeMessages(functionId);
        //计算新的数据包的数据长度(dataLength)
        int tempPackageLength =
            Util.instance!.toUShort(tempData, DATA_LENGTH_INDEX, DATA_LENGTH_SIZE);
        int newPackageLength = tempPackageLength + dataLength;
        var packageLength = Util.instance!.short2Bytes(newPackageLength);
        tempData[DATA_LENGTH_INDEX] = packageLength[0];
        tempData[DATA_LENGTH_INDEX + 1] = packageLength[1];
        //拼接数据
        List<int> newResult = tempData;
        newResult.addAll(data);
        //将本地数据清空
        _functionMap.remove(functionId);
        Log.d("最后一帧:  ${newResult}");
        //返回拼装后的数据
        return newResult;
      }
    }
  }

//endregion

// --------------------------------------------------------------------------------------------
  List<int> copyFrom(List<int> src, int off, int len) {
    // return Arrays.copyOfRange(src, off, off + len);
    List<int> bits = List.filled(len, 0);
    var i = off;
    var j = 0;
    while (i < src.length && j < len) {
      bits[j] = src[i];
      i++;
      j++;
    }
    return bits;
  }
}

class MyHandler {
  MyHandler({required this.listener});

  final MyCallback listener;

  final Map<int, Timer> _timerMap = {};

  sendEmptyMessageDelayed(int id, Duration duration) {
    var timer = Timer(duration, () {
      if (_timerMap.containsKey(id)) {
        _timerMap.remove(id);
      }
      listener(id);
    });
    _timerMap[id] = timer;
  }

  void sendEmptyMessage(int id) {
    removeMessages(id);
    listener(id);
  }

  void removeMessages(int id) {
    // 如果任务已经存在，则取消任务
    if (_timerMap.containsKey(id)) {
      _timerMap[id]?.cancel();
      _timerMap.remove(id);
    }
  }
}
